﻿// Entity Framework MapTileStore - http://maptilestore.codeplex.com/
// Copyright © 2012 Majid Qaraee
// Licensed under the Microsoft Public License (Ms-PL)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MapEntity.Model;
using System.Diagnostics;

namespace MapEntity.Services
{
    public class TileService
    {
        TilesDataContext db = new TilesDataContext();

        public TileService()
        {

        }
        public Tile GetTile(string key)
        {
            TileType tileType = TileType.Pars(key);

            if (tileType == null)
                return null;
            try
            {
                var tile = from t in db.Tiles
                           where t.Provider.SourceName == tileType.SourceName &&
                    t.ZoomLevel == tileType.ZoomLevel &&
                    t.X == tileType.X &&
                    t.Y == tileType.Y
                           select t;

                if (tile.Any())
                {
                    return tile.First();
                }
                return null;
            }
            catch (Exception ex)
            {
                Trace.TraceWarning("Get Tile from database failed : {0}", ex.Message);
                return null;
            }
        }

        public byte[] GetTileImage(string key)
        {
            Tile tile = GetTile(key);

            if (tile == null)
                return null;

            return tile.ImageTileSource.Image;
        }

        public Tile GetTile(TileType tileType)
        {
            if (tileType == null)
                return null;
            try
            {
                var tile = from t in db.Tiles
                           where t.Provider.SourceName == tileType.SourceName &&
                    t.ZoomLevel == tileType.ZoomLevel &&
                    t.X == tileType.X &&
                    t.Y == tileType.Y
                           select t;

                if (tile.Any())
                {
                    return tile.First();
                }
                return null;
            }
            catch (Exception ex)
            {
                Trace.TraceWarning("Get Tile from database failed : {0}", ex.Message);
                return null;
            }
        }

        public byte[] GetTileImage(TileType tileType)
        {
            Tile tile = GetTile(tileType);

            if (tile == null)
                return null;

            return tile.ImageTileSource.Image;
        }

        public bool AddOrUpdateTile(TileType tileType)
        {
            Tile tile;

            ImageTileSource newImageTileSource = new ImageTileSource() { Image = tileType.Image };

            if (tileType == null)
                return false;

            try
            {
                var tiles = db.Tiles.Where(t => t.X == tileType.X && t.Y == tileType.Y && t.ZoomLevel == tileType.ZoomLevel && t.Provider.SourceName == tileType.SourceName);

                if (tiles.Any())
                {
                    tile = tiles.First();
                    tile.Date = DateTime.Now;

                    tile.ImageTileSource.Image = tileType.Image;

                    db.SaveChanges();
                }
                else
                {
                    tile = new Tile();
                    
                    tile.ProviderId = db.Providers.Where(p => p.SourceName == tileType.SourceName).First().Id;
                    tile.ZoomLevel = tileType.ZoomLevel;
                    tile.X = tileType.X;
                    tile.Y = tileType.Y;
                    tile.Date = DateTime.Now;

                    db.ImageTileSources.Add(newImageTileSource);

                    db.SaveChanges();

                    tile.ImageTileSourceId = newImageTileSource.Id;

                    db.Tiles.Add(tile);

                    db.SaveChanges();
                }

                return true;
            }
            catch (Exception ex)
            {
                Trace.TraceWarning("Save Tile to database failed : {0}", ex.Message);
                return false;
            }
        }

        public bool AddOrUpdateTile(string key, byte[] image)
        {
            Tile tile = new Tile();

            TileType tileType = TileType.Pars(key);

            if (tileType == null)
                return false;

            tileType.Image = image;

            return AddOrUpdateTile(tileType);
        }

        public TileType RemovTile(string key)
        {
            Tile tile = GetTile(key);

            try
            {
                if (tile != null)
                {
                    db.ImageTileSources.Remove(tile.ImageTileSource);

                    db.SaveChanges();

                    db.Tiles.Remove(tile);

                    db.SaveChanges();

                    return TileType.Pars(key);
                }
                else
                    return null;

            }
            catch (Exception ex)
            {
                Trace.TraceWarning("Remove Tile from database failed : {0}", ex.Message);
                return null;
            }
        }
    }
}
